package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.mapper.*;
import com.ruoyi.business.service.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.WebSocketConstants;
import com.ruoyi.common.constant.leavsConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.dto.*;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.domain.vo.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.date.DateTimeUtil;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * 请假Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-16
 */
@Service
public class WsdLeavesServiceImpl extends ServiceImpl<WsdLeavesMapper, WsdLeaves>  implements IWsdLeavesService {

    @Autowired
    private WsdLeavesMapper wsdLeavesMapper;
    @Autowired
    private IWsdStudentsService wsdStudentsService;
    @Autowired
    private WsdLeaveRecordsMapper wsdLeaveRecordsMapper;

    @Autowired
    private WsdRefundTransactionsMapper wsdRefundTransactionsMapper;
    @Autowired
    private IWsdRoleClassService wsdRoleClassService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private IWsdMealRefundsService wsdMealRefundsService;

    @Autowired
    private IWsdCanteenBalanceService wsdCanteenBalanceService;

    @Autowired
    private IWsdLeavesService wsdLeavesService;

    @Autowired
    private IWsdRechargeRefundService wsdRechargeRefundService;

    @Autowired
    private IWsdPaymentRecordsService wsdPaymentRecordsService;

    @Autowired
    private WsdRechargeRefundMapper wsdRechargeRefundMapper;
    @Autowired
    private IWsdUserAccountService wsdUserAccountService;
    @Autowired
    private IWsdLeaveRecordsService wsdLeaveRecordsService;
    @Autowired
    private ISysUserService userService;
    /**
     * 查询请假
     *
     * @param id 请假主键
     * @return 请假
     */
    @Override
    public WsdLeaves selectWsdLeavesById(Long id) {
        return wsdLeavesMapper.selectWsdLeavesById(id);
    }


    /**
     * 查询请假列表
     *
     * @param
     * @return 请假
     */
    @Override
    public List<wsdLeavesVO> selectWsdLeavesList(wsdLeavesDTO wsdLeavesDTO) {
        List<wsdLeavesVO> wsdLeavesList = wsdLeavesMapper.selectWsdLeavesLists(wsdLeavesDTO);
        return wsdLeavesList;
    }
    @Override
    public List<WsdLeaves> wsdLeavesList(WsdLeaves wsdLeavesList) {
        List<WsdLeaves> wsdLeavesLists = wsdLeavesMapper.wsdLeavesList(wsdLeavesList);
        return wsdLeavesLists;
    }

    /**
     * 新增请假
     *
     * @param wsdLeaves 请假
     * @return 结果
     */
    @Override
    public int insertWsdLeaves(WsdLeaves wsdLeaves)
    {
        return wsdLeavesMapper.insertWsdLeaves(wsdLeaves);
    }

    /**
     * 修改请假
     *
     * @param wsdLeaves 请假
     * @return 结果
     */
    @Override
    public int updateWsdLeaves(WsdLeaves wsdLeaves) {
        return wsdLeavesMapper.updateWsdLeaves(wsdLeaves);
    }

    /**
     * 批量删除请假
     *
     * @param ids 需要删除的请假主键
     * @return 结果
     */
    @Override
    public int deleteWsdLeavesByIds(Long[] ids) {
        return wsdLeavesMapper.deleteWsdLeavesByIds(ids);
    }

    /**
     * 删除请假信息
     *
     * @param id 请假主键
     * @return 结果
     */
    @Override
    public int deleteWsdLeavesById(Long id) {
        //把请假期间的餐费退款记录表删除
        LambdaQueryWrapper<WsdMealRefunds> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WsdMealRefunds::getLeaveId,id);
        wsdMealRefundsService.remove(wrapper);
        return wsdLeavesMapper.deleteWsdLeavesById(id);
    }


    /**
     * 提交请假请求
     * @param
     * @return
     */
    @Override
    @Transactional
    public int submitLeave(submitLeaveDTO submitLeaveDTO) {
        String currentDateString = DateTimeUtil.getCurrentDateString();
        RechargeRefundVO rechargeRefundVO = wsdRechargeRefundMapper.existsActiveSemester(currentDateString,submitLeaveDTO.getSchoolId());
        if (rechargeRefundVO == null) {
            throw new RuntimeException("出错啦，请联系管理员！!");
        }
        //新增请假,把状态改为待审批
        WsdLeaves wsdLeaves = new WsdLeaves();
        BeanUtils.copyProperties(submitLeaveDTO,wsdLeaves);
        wsdLeaves.setStatus(leavsConstants.XIAOJIA.longValue());
        wsdLeaves.setParentId(submitLeaveDTO.getUserId());
        wsdLeaves.setStudentId(Long.parseLong(submitLeaveDTO.getStudentId()));
        WsdStudents wsdStudents = wsdStudentsService.selectWsdStudentsById( Long.valueOf( submitLeaveDTO.getStudentId() ) );
        wsdLeaves.setClassId( wsdStudents.getClassId() );
        wsdLeaves.setConfigId( rechargeRefundVO.getConfigId() );
        this.save(wsdLeaves);
        BigDecimal refundAmount = BigDecimal.ZERO;
        //插入请假期间的餐费退款记录表
        for (RefundAvailabilityDTO refundAvailabilityVO : submitLeaveDTO.getRefundAvailabilityVOS()) {
//            if (!refundAvailabilityVO.getBreakfast() && !refundAvailabilityVO.getLunch() && !refundAvailabilityVO.getDinner()){
//                continue;
//            }
            //根据学生id和学期查询订单号
//            String currentDateString = DateTimeUtil.getCurrentDateString();
//            RechargeRefundVO rechargeRefundVO = wsdRechargeRefundService.existsActiveSemester(submitLeaveDTO.getSchoolId(),currentDateString);
//            LambdaQueryWrapper<WsdPaymentRecords> wrapper = new LambdaQueryWrapper<>();
//            wrapper.eq(WsdPaymentRecords::getStudentId,Long.valueOf( submitLeaveDTO.getStudentId() ));
//            wrapper.eq(WsdPaymentRecords::getConfigId,rechargeRefundVO.getConfigId());
//            wrapper.eq(WsdPaymentRecords::getIsPaid,true);
            //拿到充值的那个订单号
            //WsdPaymentRecords wsdPaymentRecords = wsdPaymentRecordsService.getOne(wrapper);

            /*WsdPaymentRecords wsdPaymentRecords1 = new WsdPaymentRecords();
            wsdPaymentRecords1.setStudentId( Long.valueOf( submitLeaveDTO.getStudentId() ) );
            wsdPaymentRecords1.setConfigId( rechargeRefundVO.getConfigId() );
            List<WsdPaymentRecords> wsdPaymentRecords = wsdPaymentRecordsService.wsdPaymentRecords(wsdPaymentRecords1);
            String s = "";
            Integer rechargeType = -1;
            Boolean have = false;
            for (WsdPaymentRecords wsdPaymentRecordss : wsdPaymentRecords){
                if (wsdPaymentRecordss.getBalanceFee().compareTo( BigDecimal.ZERO) == 0){
                    continue;
                }else if (wsdPaymentRecordss.getBalanceFee().compareTo(BigDecimal.ZERO) > 0){
                    s = wsdPaymentRecordss.getTransactionId();
                    rechargeType = wsdPaymentRecordss.getRechargeType();
                    have = true;
                }
            }
            if (!have){
                throw new RuntimeException("找不到可退款的充值订单，请联系管理员！!");
            }
            //现金支付
            if (rechargeType == 2){
                WsdUserAccount wsdUserAccount = new WsdUserAccount();
                wsdUserAccount.setAccountId( submitLeaveDTO.getAccountId() );
                wsdUserAccount.setBankNumber( submitLeaveDTO.getBankNumber() );
                wsdUserAccount.setName( submitLeaveDTO.getName() );
                wsdUserAccount.setPhone( submitLeaveDTO.getPhone() );
                wsdUserAccount.setUserId( submitLeaveDTO.getUserId() );
                if (submitLeaveDTO.getAccountId()==null) {
                    wsdUserAccountService.insertWsdUserAccount( wsdUserAccount );
                }else {
                    wsdUserAccountService.updateWsdUserAccount( wsdUserAccount );
                }
                if (wsdLeaves.getAccountId()==null){
                    WsdLeaves wsdLeaves1 = new WsdLeaves();
                    wsdLeaves1.setId( wsdLeaves.getId() );
                    wsdLeaves1.setAccountId( wsdLeaves.getAccountId() );
                    this.updateById(wsdLeaves1);
                }
            }*/

            //计算退费金额
            refundAmount = wsdRechargeRefundService.calculateTotalRefund(refundAvailabilityVO.getBreakfast(), refundAvailabilityVO.getLunch(),refundAvailabilityVO.getDinner(),submitLeaveDTO.getSchoolId(),rechargeRefundVO);
            //插入请假期间餐费退款记录表
             WsdMealRefunds wsdMealRefunds = new WsdMealRefunds();
            wsdMealRefunds.setLeaveId(wsdLeaves.getId());
            wsdMealRefunds.setStudentId(Long.valueOf(submitLeaveDTO.getStudentId()));
            wsdMealRefunds.setRefundDate(refundAvailabilityVO.getDateTime());
            //进行数据转换
            wsdMealRefunds.setBreakfast(refundAvailabilityVO.getBreakfast());
            wsdMealRefunds.setLunch(refundAvailabilityVO.getLunch());
            wsdMealRefunds.setDinner(refundAvailabilityVO.getDinner());
            wsdMealRefunds.setChecked(refundAvailabilityVO.getChecked());
            wsdMealRefunds.setChecked2(refundAvailabilityVO.getChecked2());
            wsdMealRefunds.setChecked3(refundAvailabilityVO.getChecked3());
            //计算金额
            wsdMealRefunds.setRefundAmount(refundAmount);
            wsdMealRefunds.setStatus(2);
            //wsdMealRefunds.setTransactionId(s);
            wsdMealRefundsService.save(wsdMealRefunds);
            //生成退款流水
            WsdRefundTransactions wsdRefundTransactions = new WsdRefundTransactions();
            wsdRefundTransactions.setUserId(submitLeaveDTO.getUserId());
            wsdRefundTransactions.setStudentId(Long.valueOf(submitLeaveDTO.getStudentId()));
            //订单号
            //wsdRefundTransactions.setTransactionId(s);
            wsdRefundTransactions.setRefundAmount(refundAmount);
            wsdRefundTransactions.setMealRefundsId(wsdMealRefunds.getMealRefundsId());
            wsdRefundTransactions.setStatus(0);
            wsdRefundTransactions.setReason(submitLeaveDTO.getReason());
        }
        return 1;

    }
    @Override
    @Transactional
    public int cancellation(submitLeaveDTO submitLeaveDTO) {
        //新增请假,把状态改为待审批
        WsdLeaves wsdLeaves = new WsdLeaves();
        wsdLeaves.setEndTime( submitLeaveDTO.getEndTime() );
        //待班主任确定状态
        wsdLeaves.setStatus(leavsConstants.UNAPPROVED.longValue());
        wsdLeaves.setId( submitLeaveDTO.getId() );
        wsdLeaves.setAccountId( submitLeaveDTO.getAccountId() );
        this.updateById(wsdLeaves);
        WsdLeaves wsdLeavess = this.selectWsdLeavesById(submitLeaveDTO.getId());
        WsdUserAccount wsdUserAccount = new WsdUserAccount();
        wsdUserAccount.setAccountId( submitLeaveDTO.getAccountId() );
        wsdUserAccount.setBankNumber( submitLeaveDTO.getBankNumber() );
        wsdUserAccount.setName( submitLeaveDTO.getName() );
        wsdUserAccount.setPhone( submitLeaveDTO.getPhone() );
        wsdUserAccount.setUserId( wsdLeavess.getParentId() );
        WsdUserAccount wsdUserAccount1 = new WsdUserAccount();
        wsdUserAccount1.setUserId(wsdLeavess.getParentId());
        WsdUserAccount wsdUserAccount2 = wsdUserAccountService.selectWsdUserAccount( wsdUserAccount1 );
        if (submitLeaveDTO.getAccountId()==null && wsdUserAccount2 == null) {
            wsdUserAccountService.insertWsdUserAccount( wsdUserAccount );
        }else {
            wsdUserAccountService.updateWsdUserAccount( wsdUserAccount );
        }
        if (wsdLeavess.getAccountId()==null){
            WsdLeaves wsdLeaves1 = new WsdLeaves();
            wsdLeaves1.setId( wsdLeavess.getId() );
            WsdUserAccount wsdUserAccount3 = new WsdUserAccount();
            wsdUserAccount3.setUserId(wsdLeavess.getParentId());
            WsdUserAccount wsdUserAccount4 = wsdUserAccountService.selectWsdUserAccount( wsdUserAccount3 );
            wsdLeaves1.setAccountId( wsdUserAccount4.getAccountId() );
            this.updateById(wsdLeaves1);
        }

        WsdRechargeRefund rechargeRefundVO = wsdRechargeRefundMapper.selectWsdRechargeRefundByConfigId(wsdLeavess.getConfigId());
        if (rechargeRefundVO == null) {
            throw new RuntimeException("出错啦，请联系管理员！!");
        }
        wsdMealRefundsService.deleteWsdMealRefundsByLeaveId( wsdLeavess.getId() );
        BigDecimal refundAmount = BigDecimal.ZERO;
        //插入请假期间的餐费退款记录表
        for (RefundAvailabilityDTO refundAvailabilityVO : submitLeaveDTO.getRefundAvailabilityVOS()) {
            //计算退费金额
            refundAmount = wsdRechargeRefundService.calculateTotalRefund2(refundAvailabilityVO.getBreakfast(), refundAvailabilityVO.getLunch(),refundAvailabilityVO.getDinner(),submitLeaveDTO.getSchoolId(),rechargeRefundVO);
            //插入请假期间餐费退款记录表
            WsdMealRefunds wsdMealRefunds = new WsdMealRefunds();
            wsdMealRefunds.setLeaveId(wsdLeavess.getId());
            wsdMealRefunds.setStudentId(Long.valueOf(submitLeaveDTO.getStudentId()));
            wsdMealRefunds.setRefundDate(refundAvailabilityVO.getDateTime());
            //进行数据转换
            wsdMealRefunds.setBreakfast(refundAvailabilityVO.getBreakfast());
            wsdMealRefunds.setLunch(refundAvailabilityVO.getLunch());
            wsdMealRefunds.setDinner(refundAvailabilityVO.getDinner());
            wsdMealRefunds.setChecked(refundAvailabilityVO.getChecked());
            wsdMealRefunds.setChecked2(refundAvailabilityVO.getChecked2());
            wsdMealRefunds.setChecked3(refundAvailabilityVO.getChecked3());
            //计算金额
            wsdMealRefunds.setRefundAmount(refundAmount);
            wsdMealRefunds.setStatus(2);
            //wsdMealRefunds.setTransactionId(s);
            wsdMealRefundsService.save(wsdMealRefunds);
        }
        //插入请假审批表/审核记录
//        WsdLeaveRecords wsdLeaveRecords = new WsdLeaveRecords();
//        wsdLeaveRecords.setLeaveId(wsdLeavess.getId());
//        wsdLeaveRecords.setSchoolId(wsdLeavess.getSchoolId());
//        wsdLeaveRecords.setSchoolApprovalStatus(leavsConstants.UNAPPROVED.longValue());
//        wsdLeaveRecords.setParentApprovalStatus(leavsConstants.SUBMITTED.longValue());
//        //新增
//        return wsdLeaveRecordsMapper.insert(wsdLeaveRecords);
        return 1;

    }
    /**
     * 请假统计
     *
     * @return
     */
    @Override
    public List<leaveStatisticsVO> leaveStatistics(leaveStatisticsDTO leaveStatisticsDTO) {
        List<leaveStatisticsVO> leaveStatisticsVO = wsdLeavesMapper.leaveStatistics(leaveStatisticsDTO);
        return leaveStatisticsVO;
    }

    /**
     * 请假信息
     *
     * @param leaveSummaryDTO
     * @return
     */
    @Override
    public List<LeaveSummaryVO> LeaveSummary(LeaveSummaryDTO leaveSummaryDTO) {
        List<LeaveSummaryVO> leaveSummaryVOS = new ArrayList<>();
        //根据当前登录用户来进行查询学生数据
        SysUser user = getLoginUser().getUser();
        leaveSummaryDTO.setSchoolId(user.getSchoolId().toString());
        String userType = user.getUserType();
        if (Constants.Program.equals(userType)) {
            //家长
            leaveSummaryVOS = wsdLeavesMapper.LeaveSummary(leaveSummaryDTO);
            return leaveSummaryVOS;
        } else {
            //管理员
            //查询用户绑定的角色id
            List<SysRole> sysRoles = roleService.selectRolesUserByUserId(user.getUserId());
            if (ObjectUtils.isEmpty(sysRoles)) {
                throw new RuntimeException("你还没有配置角色,请联系管理员");
            }else {
                List<Long> roleIds = sysRoles.stream()
                        .map(SysRole::getRoleId)  // 提取每个角色的 roleId
                        .collect(Collectors.toList());  // 收集结果到一个 List 中
                LambdaQueryWrapper<WsdRoleClass> wrapper = new LambdaQueryWrapper<>();
                wrapper.in(WsdRoleClass::getRoleId, roleIds);
                List<WsdRoleClass> wsdRoleClassList = wsdRoleClassService.list(wrapper);
                List<Long> classIds = wsdRoleClassList.stream().map(WsdRoleClass::getClassId).collect(Collectors.toList());
                if (StringUtils.isEmpty(classIds)) {
                    throw new RuntimeException("你还没有绑定班级");
                }
                //根据班级id查询数据
                leaveSummaryVOS = wsdLeavesMapper.LeaveSummaryByClassIds(classIds);
            }
            if (StringUtils.isEmpty(leaveSummaryVOS)) {
                throw new RuntimeException("没有请假记录");
            }
        }
        return leaveSummaryVOS;
    }

    /**获取请假详细信息
     * @param leaveSummaryDTO
     * @return
     */
    @Override
    public LeaveSummaryVO getInfo(LeaveSummaryDTO leaveSummaryDTO) {
        LeaveSummaryVO leaveSummaryVOS =  wsdLeavesMapper.getInfo(leaveSummaryDTO);
        return leaveSummaryVOS;
    }
    @Override
    public LeaveSummaryVO getForId(Long id) {
        LeaveSummaryVO leaveSummaryVOS =  wsdLeavesMapper.getForId(id);
        List<RefundAvailabilityVO> refundAvailabilityVOS = wsdMealRefundsService.selectWsdMealRefundsByLeaveIds(id);
        leaveSummaryVOS.setRefundAvailabilityVOS( refundAvailabilityVOS );
        //审核记录
        WsdLeaveRecords wsdLeaveRecords = new WsdLeaveRecords();
        wsdLeaveRecords.setLeaveId( id );
        List<WsdLeaveRecords> wsdLeaveRecordsList = wsdLeaveRecordsService.wsdLeaveRecordsList( wsdLeaveRecords );
        for (int i = 0; i < wsdLeaveRecordsList.size(); i++) {
            WsdLeaveRecords record = wsdLeaveRecordsList.get(i);
            SysUser sysUser = userService.selectUserById(record.getSchoolApproverId());
            String stateName = record.getSchoolApprovalStatus() == 1 ? "审核通过" : "不通过";
            record.setStatusName(stateName);
            String reviewerRole = record.getParentApprovalStatus() == 1 ? "(财务)" : "(老师)";
            String reviewerName = String.format("审核人：%s%s", sysUser.getNickName(), reviewerRole);
            record.setName(reviewerName);
            String comment = String.format("审核意见：%s", record.getSchoolComment());
            record.setSchoolComment(comment);
            record.setIsNow(i == 0 ? 1 : 0);
        }
        leaveSummaryVOS.setWsdLeaveRecordsList( wsdLeaveRecordsList );
        return leaveSummaryVOS;
    }

    /**
     * 查询审核和未审核请假记录列表
     *
     * @param auditing
     * @param schoolId
     * @return
     */
    @Override
    public List<wsdLeavesVO> selectWsdLeaveslistAuditing(Boolean auditing, Long schoolId) {
        // 根据是否审核的布尔值，决定状态列表内容
        List<Integer> statusList = (Boolean.TRUE.equals(auditing)) ? Arrays.asList(leavsConstants.APPROVE, leavsConstants.ERFUSE) : Arrays.asList(leavsConstants.UNAPPROVED);
        // 调用 Mapper 方法，并传入列表参数
        List<wsdLeavesVO> wsdLeavesList = wsdLeavesMapper.selectWsdLeaveslistAuditing(schoolId, statusList);
        return wsdLeavesList;
    }

    @Override
    public List<Map<String, Object>> queryLeaveCounts(LocalDate today, LocalDate startOfWeek, LocalDate endOfWeek, LocalDate startOfMonth, LocalDate endOfMonth, Long schoolId) {
        return wsdLeavesMapper.queryLeaveCounts(today, startOfWeek, endOfWeek, startOfMonth, endOfMonth,schoolId);
    }

    /**
     * 获取一周内每天的请假人数统计  优化(mysql 8.0的话可以使用数据库处理)
     * @param schoolId 学校ID，用于查询指定学校的请假记录
     * @return ChartDataVO，包含日期标签和对应的请假人数
     */
    @Override
    public ChartDataVO queryWeeklyLeaveCounts(Long schoolId) {

        // 设定一周的开始日期为本周一
        LocalDate startOfWeek = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 设定一周的结束日期为开始日期后的第六天（本周日）
        LocalDate endOfWeek = startOfWeek.plusDays(6);

        // 从数据库获取本周的请假记录
        List<Map<String, Object>> leaveRecords = wsdLeavesMapper.queryWeeklyLeaveCounts(schoolId, startOfWeek, endOfWeek);

        // 使用HashMap存储每天的请假人数
        Map<LocalDate, Integer> leaveCounts = new HashMap<>();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;

        // 遍历请假记录
        for (Map<String, Object> record : leaveRecords) {
            // 解析开始和结束时间
            LocalDateTime startDateTime = LocalDateTime.parse(record.get("start_time").toString(), dateTimeFormatter);
            LocalDateTime endDateTime = LocalDateTime.parse(record.get("end_time").toString(), dateTimeFormatter);
            LocalDate start = startDateTime.toLocalDate();
            LocalDate end = endDateTime.toLocalDate();

            // 统计每一天的请假人数
            while (!start.isAfter(end)) {
                if (!start.isBefore(startOfWeek) && !start.isAfter(endOfWeek)) {
                    leaveCounts.put(start, leaveCounts.getOrDefault(start, 0) + 1);
                }
                start = start.plusDays(1);
            }
        }

        // 准备用于图表显示的标签和值
        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd EEEE", Locale.SIMPLIFIED_CHINESE);

        // 生成图表数据
        for (LocalDate date = startOfWeek; !date.isAfter(endOfWeek); date = date.plusDays(1)) {
            labels.add(dateFormatter.format(date));
            values.add(leaveCounts.getOrDefault(date, 0));  // 如果某天无请假记录，则计为0
        }

        // 返回图表数据对象
        return new ChartDataVO(labels, values,null);
    }


    @Override
    public ChartDataVO queryMonthlyLeaveCounts(Long schoolId, Optional<Integer> year, Optional<Integer> month) {

        // 如果未指定年份，默认使用当前年份
        int queryYear = year.orElse(LocalDate.now().getYear());

        LocalDate startOfMonth;
        LocalDate endOfMonth;

        // 如果指定了月份，则只查询该月的数据
        if (month.isPresent()) {
            startOfMonth = LocalDate.of(queryYear, month.get(), 1); // 月份的开始日期
            endOfMonth = startOfMonth.with(TemporalAdjusters.lastDayOfMonth()); // 月份的结束日期
        } else {
            // 如果未指定月份，则查询整个年份的数据
            startOfMonth = LocalDate.of(queryYear, 1, 1); // 年份的开始日期
            endOfMonth = LocalDate.of(queryYear, 12, 31); // 年份的结束日期
        }

        List<Map<String, Object>> results = wsdLeavesMapper.queryMonthlyLeaveCounts(schoolId,startOfMonth,endOfMonth);
        Map<Integer, Integer> leaveCounts = new HashMap<>();
        results.forEach(result -> {
            Integer resultMonth = (Integer) result.get("month"); // 从结果中获取月份
            leaveCounts.put(resultMonth, ((Number) result.get("leaveCount")).intValue()); // 将请假人数放入Map中
        });

        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM", Locale.SIMPLIFIED_CHINESE); // 日期格式化器

        // 生成返回的标签和值
        if (month.isPresent()) {
            labels.add(monthFormatter.format(startOfMonth)); // 如果指定月份，只添加该月
            values.add(leaveCounts.getOrDefault(month.get(), 0)); // 添加该月的请假人数，如果无数据则为0
        } else {
            for (int m = 1; m <= 12; m++) {
                LocalDate date = LocalDate.of(queryYear, m, 1);
                labels.add(monthFormatter.format(date)); // 添加每个月的标签
                values.add(leaveCounts.getOrDefault(m, 0)); // 添加每个月的请假人数，如果无数据则为0
            }
        }
        return new ChartDataVO(labels, values,null);
    }

    /**
     * 获取年的柱状图
     * @param schoolId
     * @return
     */
    @Override
    public ChartDataVO queryYearlyLeaveCounts(Long schoolId) {

        int currentYear = LocalDate.now().getYear();
        int startYear = currentYear - 4;  // 获取过去5年的数据

        List<Map<String, Object>> results = wsdLeavesMapper.queryYearlyLeaveCounts(schoolId,startYear,currentYear);

        Map<Integer, Integer> leaveCounts = new HashMap<>();
        results.forEach(result -> {
            Integer year = (Integer) result.get("year");
            leaveCounts.put(year, ((Number) result.get("leaveCount")).intValue());
        });

        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();

        for (int year = startYear; year <= currentYear; year++) {
            labels.add(String.valueOf(year));
            values.add(leaveCounts.getOrDefault(year, 0));
        }
        ChartDataVO chartDataVO = new ChartDataVO(labels, values,null);
        return chartDataVO;
    }

    /**
     * 获取今天的请假情况
     *
     * @return
     */
    @Override
    public leaveNumberVO todayLeaveStatus(Long schoolId) {
        leaveNumberVO leaveNumberVO = new leaveNumberVO();
        //查询请假人数
        leaveNumberVO leaveStatus = wsdLeavesMapper.todayLeaveStatus(schoolId);
        BeanUtils.copyProperties(leaveStatus, leaveNumberVO);
        //查询订餐人数
        Integer mealLeaves = wsdCanteenBalanceService.selectStudentCountBySchool(schoolId);
        leaveNumberVO.setMealLeaves(mealLeaves);
        //查询停餐人数
        Integer stopLeaves =  wsdLeavesService.countTodayApprovedLeaves(schoolId);
        leaveNumberVO.setStopLeaves(stopLeaves);
        //把订餐人数减掉停餐人数
        leaveNumberVO.setDiningLeaves(mealLeaves - stopLeaves);

        //退费情况
        //申请退费=请假人数
        leaveNumberVO leaveStatusAppl = wsdLeavesMapper.leaveStatusReturn(schoolId);
        leaveNumberVO.setApplyRefund( leaveStatusAppl.getApplyRefund() );
        //未退费
        leaveNumberVO.setNoRefunded( leaveStatusAppl.getNoRefunded() );
        //已退费
        leaveNumberVO leaveStatusReturn = wsdRefundTransactionsMapper.leaveStatusReturn(schoolId);
        leaveNumberVO.setRefunded( leaveStatusReturn.getRefunded() );
        return leaveNumberVO;
    }

    /**
     * 代办事项显示
     *
     * @param schoolId
     * @return
     */
    @Override
    public AgencyMattersVO agencyMatters(Long schoolId) {
        List<AgencyMattersVO> list = wsdLeavesMapper.agencyMatters(schoolId, Constants.STATUSONE);
        // 将每个AgencyMattersVO转换为一个Map
        List<Map<String, Object>> mapList = list.stream().map(vo -> {
            Map<String, Object> map = new HashMap<>();
            map.put("studentName", vo.getStudentName() + WebSocketConstants.MESSAGE_STATUS_PENDING_APPROVAL);
            map.put("leaveCreatedAt", vo.getLeaveCreatedAt());
            return map;
        }).collect(Collectors.toList());
        AgencyMattersVO agencyMattersVO = new AgencyMattersVO();
        agencyMattersVO.setLeaveCounts(mapList);
        return agencyMattersVO;
    }

    /**
     * 查询当前学生在今天有没有请假
     *
     * @param studentId
     * @param startTime
     * @param endTime
     */
    @Override
    public int selectStudentsWsdLeave(String studentId, @NotBlank Date startTime, @NotBlank Date endTime) {
        //获取今天的时间
        // LocalDate today = LocalDate.now();
        // // 获取今天的开始时间（午夜开始）
        // LocalDateTime startOfDay = today.atStartOfDay();
        // // 获取今天的结束时间（午夜前一秒）
        // LocalDateTime endOfDay = LocalDateTime.of(today, LocalTime.MAX);
        // // 格式化日期时间输出
        // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // String start_time = startOfDay.format(formatter);
        // String end_time = endOfDay.format(formatter);
        return wsdLeavesMapper.selectStudentsWsdLeave(studentId,startTime,endTime);
    }

    /**
     * 查询停餐人数
     *
     * @param schoolId
     * @return
     */
    @Override
    public Integer countTodayApprovedLeaves(Long schoolId) {
       return wsdLeavesMapper.countTodayApprovedLeaves(schoolId);
    }

    /**
     * 获取学生请假早中晚餐
     *
     * @param leaveSummaryDTO
     * @return
     */
    @Override
    public List<RefundAvailabilityVO> getInfoStudent(LeaveSummaryDTO leaveSummaryDTO) {
        List<RefundAvailabilityVO> refundAvailabilityVOS = new ArrayList<>();
        String startTime = leaveSummaryDTO.getStartTime();
        String endTime = leaveSummaryDTO.getEndTime();
        List<String> datesBetween = DateTimeUtil.getDatesBetween(startTime, endTime);
        for (String s : datesBetween) {
           RefundAvailabilityVO refundAvailabilityVO = wsdMealRefundsService.selectWsdMealRefundsByLeaveId(leaveSummaryDTO.getLeaveId(), s);
           refundAvailabilityVOS.add(refundAvailabilityVO);
        }
        return refundAvailabilityVOS;
    }
}
